from PyQt5.QtCore import QRegExp
from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat, QColor, QFont


class JavaScriptHighlighter(QSyntaxHighlighter):
    """JavaScript语法高亮器"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.highlighting_rules = []
        self.setup_rules()
    
    def setup_rules(self):
        """设置JavaScript语法高亮规则"""
        
        # 关键字格式 - 橙色
        keyword_format = QTextCharFormat()
        keyword_format.setForeground(QColor('#CE713A'))  # 橙色
        keyword_format.setFontWeight(QFont.Bold)
        
        # JavaScript关键字列表
        js_keywords = [
            'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
            'default', 'delete', 'do', 'else', 'export', 'extends', 'finally',
            'for', 'function', 'if', 'import', 'in', 'instanceof', 'new',
            'return', 'super', 'switch', 'this', 'throw', 'try', 'typeof',
            'var', 'void', 'while', 'with', 'yield', 'let', 'await'
        ]
        
        # 为每个关键字创建规则
        for keyword in js_keywords:
            pattern = QRegExp(r'\b' + keyword + r'\b')
            self.highlighting_rules.append((pattern, keyword_format))
        
        # 数据类型和特殊值格式 - 蓝色
        datatype_format = QTextCharFormat()
        datatype_format.setForeground(QColor('#4E9AEF'))  # 蓝色
        datatype_format.setFontWeight(QFont.Bold)
        
        js_datatypes = [
            'true', 'false', 'null', 'undefined', 'NaN', 'Infinity'
        ]
        
        for datatype in js_datatypes:
            pattern = QRegExp(r'\b' + datatype + r'\b')
            self.highlighting_rules.append((pattern, datatype_format))
        
        # 函数名格式 - 青色
        function_format = QTextCharFormat()
        function_format.setForeground(QColor('#4EC9B0'))  # 青色
        function_pattern = QRegExp(r'\bfunction\s+([A-Za-z_][A-Za-z0-9_]*)')
        self.highlighting_rules.append((function_pattern, function_format))
        
        # 箭头函数格式
        arrow_function_format = QTextCharFormat()
        arrow_function_format.setForeground(QColor('#4EC9B0'))  # 青色
        arrow_function_pattern = QRegExp(r'\b([A-Za-z_][A-Za-z0-9_]*)\s*=>')
        self.highlighting_rules.append((arrow_function_pattern, arrow_function_format))
        
        # 类名格式 - 深蓝色
        class_format = QTextCharFormat()
        class_format.setForeground(QColor('#569CD6'))  # 深蓝色
        class_format.setFontWeight(QFont.Bold)
        class_pattern = QRegExp(r'\bclass\s+([A-Z][A-Za-z0-9_]*)')
        self.highlighting_rules.append((class_pattern, class_format))
        
        # 字符串格式 - 绿色
        string_format = QTextCharFormat()
        string_format.setForeground(QColor('#6A8759'))  # 绿色
        
        # 双引号字符串
        double_quote_pattern = QRegExp(r'"[^"\\]*(\\.[^"\\]*)*"')
        self.highlighting_rules.append((double_quote_pattern, string_format))
        
        # 单引号字符串
        single_quote_pattern = QRegExp(r"'[^'\\]*(\\.[^'\\]*)*'")
        self.highlighting_rules.append((single_quote_pattern, string_format))
        
        # 模板字符串
        template_string_format = QTextCharFormat()
        template_string_format.setForeground(QColor('#6A8759'))  # 绿色
        template_string_pattern = QRegExp(r'`[^`\\]*(\\.[^`\\]*)*`')
        self.highlighting_rules.append((template_string_pattern, template_string_format))
        
        # 注释格式 - 灰色
        comment_format = QTextCharFormat()
        comment_format.setForeground(QColor('#808080'))  # 灰色
        
        # 单行注释
        single_line_comment_pattern = QRegExp(r'//[^\n]*')
        self.highlighting_rules.append((single_line_comment_pattern, comment_format))
        
        # 多行注释开始和结束
        self.multi_line_comment_format = QTextCharFormat()
        self.multi_line_comment_format.setForeground(QColor('#808080'))
        
        # 多行注释开始模式
        self.comment_start_expression = QRegExp(r'/\*')
        self.comment_end_expression = QRegExp(r'\*/')
        
        # 数字格式 - 浅紫色
        number_format = QTextCharFormat()
        number_format.setForeground(QColor('#B5CEA8'))  # 浅紫色
        number_pattern = QRegExp(r'\b\d+\.?\d*\b')
        self.highlighting_rules.append((number_pattern, number_format))
        
        # 正则表达式格式 - 紫色
        regex_format = QTextCharFormat()
        regex_format.setForeground(QColor('#D16969'))  # 紫色
        regex_pattern = QRegExp(r'/(?:[^/\\]|\\.)*/[gimuy]*')
        self.highlighting_rules.append((regex_pattern, regex_format))
        
        # 变量声明格式 - 浅蓝色
        variable_format = QTextCharFormat()
        variable_format.setForeground(QColor('#9CDCFE'))  # 浅蓝色
        variable_pattern = QRegExp(r'\b(var|let|const)\s+([A-Za-z_][A-Za-z0-9_]*)')
        self.highlighting_rules.append((variable_pattern, variable_format))
        
        # 对象属性格式 - 浅绿色
        property_format = QTextCharFormat()
        property_format.setForeground(QColor('#4EC9B0'))  # 浅绿色
        property_pattern = QRegExp(r'\b([A-Za-z_][A-Za-z0-9_]*)\s*:')
        self.highlighting_rules.append((property_pattern, property_format))
        
        # 方法调用格式 - 青色
        method_call_format = QTextCharFormat()
        method_call_format.setForeground(QColor('#4EC9B0'))  # 青色
        method_call_pattern = QRegExp(r'\b([A-Za-z_][A-Za-z0-9_]*)(?=\()')
        self.highlighting_rules.append((method_call_pattern, method_call_format))
        
        # 导入导出格式 - 浅蓝色
        import_export_format = QTextCharFormat()
        import_export_format.setForeground(QColor('#9CDCFE'))  # 浅蓝色
        import_export_pattern = QRegExp(r'\b(import|export)\s+(?:[^;]+)')
        self.highlighting_rules.append((import_export_pattern, import_export_format))
    
    def highlightBlock(self, text):
        """高亮文本块"""
        # 先处理多行注释
        self.highlight_multiline_comments(text)
        
        # 然后处理其他规则
        for pattern, format_ in self.highlighting_rules:
            expression = QRegExp(pattern)
            index = expression.indexIn(text)
            while index >= 0:
                length = expression.matchedLength()
                # 检查是否已经在注释中（多行注释状态）
                if self.currentBlockState() != 1:
                    self.setFormat(index, length, format_)
                index = expression.indexIn(text, index + length)
    
    def highlight_multiline_comments(self, text):
        """处理多行注释高亮"""
        # 获取前一个块的状态
        previous_state = self.previousBlockState()
        
        start_index = 0
        
        # 如果前一个块在多行注释中，继续高亮
        if previous_state == 1:
            start_index = 0
            self.setFormat(0, len(text), self.multi_line_comment_format)
            
            # 查找注释结束位置
            end_index = self.comment_end_expression.indexIn(text)
            if end_index >= 0:
                # 注释结束，重置状态
                self.setCurrentBlockState(0)
            else:
                # 注释继续到下一行
                self.setCurrentBlockState(1)
            return
        
        # 查找多行注释开始
        start_index = self.comment_start_expression.indexIn(text)
        
        while start_index >= 0:
            # 查找注释结束
            end_index = self.comment_end_expression.indexIn(text, start_index)
            
            if end_index == -1:
                # 注释跨越多行
                self.setFormat(start_index, len(text) - start_index, self.multi_line_comment_format)
                self.setCurrentBlockState(1)
                break
            else:
                # 单行内的多行注释
                comment_length = end_index - start_index + 2
                self.setFormat(start_index, comment_length, self.multi_line_comment_format)
                start_index = self.comment_start_expression.indexIn(text, end_index + 2)